﻿using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace CIS.Web.Common
{
	/// <summary>
	/// 类名：Submit
	/// 功能：支付宝各接口请求提交类
	/// 详细：构造支付宝各接口表单HTML文本，获取远程HTTP数据
	/// 版本：3.3
	/// 修改日期：2011-07-05
	/// 说明：
	/// 以下代码只是为了方便商户测试而提供的样例代码，商户可以根据自己网站的需要，按照技术文档编写,并非一定要使用该代码。
	/// 该代码仅供学习和研究支付宝接口使用，只是提供一个参考
	/// </summary>
	public class AlipaySubmit
	{
		#region 字段
		//支付宝网关地址（新）
		private static string GATEWAY_NEW = "https://mapi.alipay.com/gateway.do?";
		//商户的私钥
		private static string _key = "";
		//编码格式
		private static string _input_charset = "";
		//签名方式
		private static string _sign_type = "";
		#endregion

		public AlipaySubmit(string key, string input_charset, string sign_type)
		{
			_key = key.Trim();
			_input_charset = input_charset.Trim().ToLower();
			_sign_type = sign_type.Trim().ToUpper();
		}

		/// <summary>
		/// 生成请求时的签名
		/// </summary>
		/// <param name="sPara">请求给支付宝的参数数组</param>
		/// <returns>签名结果</returns>
		public static string BuildRequestMysign(Dictionary<string, string> sPara)
		{
			//把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
			string prestr = Core.CreateLinkString(sPara);

			//把最终的字符串签名，获得签名结果
			string mysign = "";
			switch (_sign_type)
			{
				case "MD5":
					mysign = AlipayMD5.Sign(prestr, _key, _input_charset);
					break;
				default:
					mysign = "";
					break;
			}

			return mysign;
		}

		/// <summary>
		/// 生成要请求给支付宝的参数数组
		/// </summary>
		/// <param name="sParaTemp">请求前的参数数组</param>
		/// <returns>要请求的参数数组</returns>
		public Dictionary<string, string> BuildRequestPara(SortedDictionary<string, string> sParaTemp)
		{
			//待签名请求参数数组
			Dictionary<string, string> sPara = new Dictionary<string, string>();
			//签名结果
			string mysign = "";

			//过滤签名参数数组
			sPara = Core.FilterPara(sParaTemp);

			//获得签名结果
			mysign = BuildRequestMysign(sPara);

			//签名结果与签名方式加入请求提交参数组中
			sPara.Add("sign", mysign);
			sPara.Add("sign_type", _sign_type);

			return sPara;
		}

		/// <summary>
		/// 生成要请求给支付宝的参数数组
		/// </summary>
		/// <param name="sParaTemp">请求前的参数数组</param>
		/// <param name="code">字符编码</param>
		/// <returns>要请求的参数数组字符串</returns>
		private string BuildRequestParaToString(SortedDictionary<string, string> sParaTemp, Encoding code)
		{
			//待签名请求参数数组
			Dictionary<string, string> sPara = new Dictionary<string, string>();
			sPara = BuildRequestPara(sParaTemp);

			//把参数组中所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串，并对参数值做urlencode
			string strRequestData = Core.CreateLinkStringUrlencode(sPara, code);

			return strRequestData;
		}

		/// <summary>
		/// 建立请求，以表单HTML形式构造（默认）
		/// </summary>
		/// <param name="sParaTemp">请求参数数组</param>
		/// <param name="strMethod">提交方式。两个值可选：post、get</param>
		/// <param name="strButtonValue">确认按钮显示文字</param>
		/// <returns>提交表单HTML文本</returns>
		public string BuildRequest(SortedDictionary<string, string> sParaTemp, string strMethod, string strButtonValue)
		{
			//待请求参数数组
			Dictionary<string, string> dicPara = new Dictionary<string, string>();
			dicPara = BuildRequestPara(sParaTemp);

			StringBuilder sbHtml = new StringBuilder();

			sbHtml.Append("<form id='alipaysubmit' name='alipaysubmit' action='" + GATEWAY_NEW + "_input_charset=" + _input_charset + "' method='" + strMethod.ToLower().Trim() + "'>");

			foreach (KeyValuePair<string, string> temp in dicPara)
			{
				sbHtml.Append("<input type='hidden' name='" + temp.Key + "' value='" + temp.Value + "'/>");
			}

			//submit按钮控件请不要含有name属性
			sbHtml.Append("<input type='submit' value='" + strButtonValue + "' style='display:none;'></form>");

			sbHtml.Append("<script>document.forms['alipaysubmit'].submit();</script>");

			return sbHtml.ToString();
		}
	}
}